import lodashCloneDeep from 'lodash/cloneDeep'
/**
 * 深拷贝
 * @param value {*}
 * @return {*}
 */
export const cloneDeep = (value) => {
  return lodashCloneDeep(value)
}
/**
 * 2个对象值进行比较
 * @param objectA
 * @param objectB
 * @return {boolean}
 */
export const objectEqual = (objectA, objectB) => {
  const keysA = Object.keys(objectA)
  const keysB = Object.keys(objectB)
  if (keysA.length !== keysB.length) return false
  const keysLength = keysA.length
  for (let i = 0; i < keysLength; i++) {
    const keyA = objectA[i]
    if (!keysB.includes(keyA)) return false
    const valueA = objectA[keyA]
    const valueB = objectB[keyA]
    if (typeof valueA === 'object' && typeof valueB === 'object') {
      if (!objectEqual(valueA, valueB)) return false
    } else {
      if (valueA !== valueB) return false
    }
  }
  // 排除所有不想等的情况
  return true
}
/**
 * 节流
 * @param fn {Function} 方法
 * @param delay {Number} 延迟执行时间
 * @return {function(): void}
 */
export function throttle (fn, delay) {
  let pre = 0
  return function () {
    const args = arguments
    const now = Date.now()
    if (now - pre > delay) {
      pre = now
      fn.apply(this, args)
    }
  }
}
/**
 * 防抖
 * @param fn {Function} 方法
 * @param wait {Number} 延迟执行时间
 * @param immediate {boolean} 是否立即执行
 * @return {function(): void}
 */
export const debounce = (fn, wait, immediate) => {
  let timeout, result
  const debounced = function () {
    const context = this
    const args = arguments
    if (timeout) clearTimeout(timeout)
    if (immediate) {
      // 如果已经执行过，不再执行
      const callNow = !timeout
      timeout = setTimeout(() => {
        timeout = null
      }, wait)
      if (callNow) result = fn.apply(context, args)
    } else {
      timeout = setTimeout(() => {
        fn.apply(context, args)
      }, wait)
    }
    return result
  }
  debounced.cancel = () => {
    clearTimeout(timeout)
    timeout = null
  }
  return debounced
}

/**
 * 大写第一位字符串
 * @param str {String} 字符串
 * @return {string}
 */
export const toUpperFirstCase = (str) => {
  const first = str.charAt(0)
  const upperFirst = first.toUpperCase()
  return upperFirst + str.slice(1)
}

/**
 * 平铺数组转换为树状结构
 * @param list {Array} 数组列表
 * @param parentKey {String} 父节点名称
 * @param root {Number} 根节点值
 * @return {boolean}
 */
export const toTreeData = (list, parentKey = 'parentId', root = 0) => {
  const cloneData = cloneDeep(list)
  const tree = cloneData.filter((father) => {
    const branchArr = cloneData.filter((child) => {
      return father.id === child[parentKey]
    })
    if (branchArr.length > 0) {
      father.children = branchArr
    }
    return father[parentKey] === root
  })
  tree.forEach(row => {
    row[parentKey] = ''
  })
  return tree
}
/**
 * 判断值是否为undefined或null
 * @param value {*} 待判断值
 * @return {boolean}
 */
export const isEmpty = (value) => {
  return value === undefined || value === null
}
/**
 * 判断值是否不为undefined或null
 * @param value {*} 待判断值
 * @return {boolean}
 */
export const isNotEmpty = (value) => {
  return !isEmpty(value)
}
/**
 * 判断值是否为数组
 * @param value {*}
 * @return {boolean}
 */
export const isArray = (value) => {
  return Object.prototype.toString.call(value) === '[object Array]'
}
/**
 * 判断是否对象
 * @param value
 * @return {boolean}
 */
export const isObject = (value) => {
  return Object.prototype.toString.call(value) === '[object Object]'
}
/**
 * 判断值是否为JSON String
 * @param value
 * @return {boolean}
 */
export const isJson = (value) => {
  try {
    const obj = JSON.parse(value)
    if (typeof obj === 'object' && obj) {
      return true
    } else {
      return false
    }
  } catch (e) {
    return false
  }
}
/**
 * 下载文件
 * @param href {String} base64地址或远程地址
 * @param filename {String} 文件名
 */
export const downloadFile = (href, filename) => {
  if (href && filename) {
    const a = document.createElement('a')
    a.download = filename // 指定下载的文件名
    a.href = href //  URL对象
    a.click() // 模拟点击
    URL.revokeObjectURL(a.href) // 释放URL 对象
  }
}
/**
 * 删除一条数据后返回下一条数据
 * @param itemList 列表
 * @param index 待删除数据
 * @return {{}}
 */
export const getNextItem = (itemList, index) => {
  let result = {}
  if (index === itemList.length - 1) {
    if (index !== 0) {
      result = itemList[index - 1]
    }
  } else {
    result = itemList[index + 1]
  }
  return result
}

/**
 * @description: 耗时格式化
 * @param {*} time 毫秒
 * @return {*} timeStr eg: 22时22分22秒
 */
export const durationTimeFormat = (time) => {
  if (!time && typeof time !== 'number') return ''
  const result = []
  const seconds = Math.ceil(time / 1000)
  const minutes = Math.floor(seconds / 60)
  const hours = Math.floor(minutes / 60)
  const days = Math.floor(hours / 24)
  const months = Math.floor(days / 30)
  const years = Math.floor(months / 12)
  if (years) {
    result.push(years + '年')
  }
  if (months % 12) {
    result.push(months % 12 + '月')
  }
  if (days % 365) {
    result.push(days % 365 + '天')
  }
  if (hours % 24) {
    result.push(hours % 24 + '小时')
  }
  if (minutes % 60) {
    result.push(minutes % 60 + '分')
  }
  if (seconds % 60) {
    result.push(seconds % 60 + '秒')
  }
  return result.join('')
}
/**
 * 根据url获取query中key对应的值
 * @param key
 * @param url
 * @return {string|null}
 */
export const getQueryString = (key, url) => {
  if (isEmpty(url)) url = window.location.href
  const reg = new RegExp('(^|&|\\?)' + key + '=([^&]*)(&|$|#)', 'i')
  const r = url.match(reg)
  if (r != null) return decodeURIComponent(r[2])
  return null
}
